package org.eclipse.jdt.internal.ui.callhierarchy;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.runtime.NullProgressMonitor;

import org.eclipse.jdt.core.IAnnotation;
import org.eclipse.jdt.core.IBuffer;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IImportDeclaration;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;

/**
 * 通过buffer操作类
 * .
 * @author hehuang 20180222
 *
 */
public class ClassBufferClass implements RefactorClass {
	
	private IType type;
	
	private TemplateEngine templateEngine;
	
	public ClassBufferClass(IType type) {
		this.type = type;
	}

	public void deleteImport(IImportDeclaration importDeclaration) throws JavaModelException {
		importDeclaration.delete(true, new NullProgressMonitor());
	}

	public void addMethod(String modifier, String returnType, String methodName, TypeNamePairs parameters, Exceptions exceptions, String methodBody) throws JavaModelException {
		TemplateEngine templateEngine = getTemplateEngine();
		Map<String, String> param = new HashMap<String, String>();
		param.put("@modifier", modifier);
		param.put("@returnType", returnType);
		param.put("@methodName", methodName);
		param.put("@parameters", parameters.toString());
		param.put("@exceptions", exceptions.toString());
		param.put("@methodBody", methodBody);
		
		String contents = templateEngine.build(TemplateFlag.METHOD_DECLARATION, param);
		
		try {
			type.createMethod(contents, null, false, new NullProgressMonitor());
		} catch (Exception e) {
			Logger.info("已存在方法:" + type.getElementName() + " " + methodName);
		}
		
	}

	public void addPublicMethod(String methodName, String returnType, TypeNamePairs parameters, Exceptions exceptions, String methodBody) throws JavaModelException {
		addMethod("public", returnType, methodName, parameters, exceptions, methodBody);
	}

	public void addGetter(String fieldName, String fieldType) throws JavaModelException {
		Map<String, String> map = new HashMap<String, String>();
		map.put("@fieldName", fieldName);
		map.put("@fieldType", fieldType);
		
		// 作成interceptor,但是我现在已经不想维护了,现在已经是项目后期,直接写死
		if (fieldName.startsWith("has")) { // has的get方法不改名,直接将属性名作为方法名
			TemplateEngine templateEngine = getTemplateEngine();
			String content = templateEngine.build(TemplateFlag.FIELD_GETTER, map);
			
			try {
				type.createMethod(content, null, false, new NullProgressMonitor());
			} catch (Exception e) {
				Logger.info("已存在方法:" + type.getElementName() + " " + content);
			}
		} else if (fieldName.startsWith("is")) { // is U
			TemplateEngine templateEngine = getTemplateEngine();
			String content = templateEngine.build(TemplateFlag.FIELD_GETTER, map);
			
			try {
				type.createMethod(content, null, false, new NullProgressMonitor());
			} catch (Exception e) {
				Logger.info("已存在方法:" + type.getElementName() + " " + content);
			}
		} else {
			TemplateEngine templateEngine = getTemplateEngine();
			String content = templateEngine.build(TemplateFlag.GETTER, map);
			
			try {
				type.createMethod(content, null, false, new NullProgressMonitor());
			} catch (Exception e) {
				Logger.info("已存在方法:" + type.getElementName() + " " + content);
			}
		}
		
		
	}

	public void addGetter(String fieldName, String fieldType, String methodBody) throws JavaModelException {
		Map<String, String> map = new HashMap<String, String>();
		map.put("@fieldName", fieldName);
		map.put("@fieldType", fieldType);
		map.put("@methodBody", methodBody);
		
		// 作成interceptor,但是我现在已经不想维护了,现在已经是项目后期,直接写死
		if (fieldName.startsWith("has")) { // has的get方法不改名,直接将属性名作为方法名
			TemplateEngine templateEngine = getTemplateEngine();
			String content = templateEngine.build(TemplateFlag.FIELD_GETTER_BODY, map);
			
			try {
				type.createMethod(content, null, false, new NullProgressMonitor());
			} catch (Exception e) {
				Logger.info("已存在方法:" + type.getElementName() + " " + content);
			}
		} else if (fieldName.startsWith("is")) { // is U
			TemplateEngine templateEngine = getTemplateEngine();
			String content = templateEngine.build(TemplateFlag.FIELD_GETTER_BODY, map);
			
			try {
				type.createMethod(content, null, false, new NullProgressMonitor());
			} catch (Exception e) {
				Logger.info("已存在方法:" + type.getElementName() + " " + content);
			}
		} else {
			TemplateEngine templateEngine = getTemplateEngine();
			String content = templateEngine.build(TemplateFlag.GETTER_BODY, map);
			
			try {
				type.createMethod(content, null, false, new NullProgressMonitor());
			} catch (Exception e) {
				Logger.info("已存在方法:" + type.getElementName() + " " + content);
			}
		}
	}

	public void addSetter(String fieldName, String fieldType) throws JavaModelException {
		Map<String, String> map = new HashMap<String, String>();
		map.put("@fieldName", fieldName);
		map.put("@fieldType", fieldType);
		
		TemplateEngine templateEngine = getTemplateEngine();
		String content = templateEngine.build(TemplateFlag.SETTER, map);
		
		try {
			type.createMethod(content, null, false, new NullProgressMonitor());
		} catch (Exception e) {
			Logger.info("已存在方法:" + type.getElementName() + " " + content);
		}
		

	}

	public void addSetter(String fieldName, String fieldType, String methodBody) throws JavaModelException {
		Map<String, String> map = new HashMap<String, String>();
		map.put("@fieldName", fieldName);
		map.put("@fieldType", fieldType);
		map.put("@methodBody", methodBody);
		
		TemplateEngine templateEngine = getTemplateEngine();
		String content = templateEngine.build(TemplateFlag.SETTER_BODY, map);
		
		try {
			type.createMethod(content, null, false, new NullProgressMonitor());
		} catch (Exception e) {
			Logger.info("已存在方法:" + type.getElementName() + " " + content);
		}
		
	}

	public void deleteAnnotation(IField field, String annoName) throws JavaModelException {
		IAnnotation[] anns = field.getAnnotations();
		
		for (IAnnotation ann
				: anns) {
			if (annoName != null
					&& annoName.equalsIgnoreCase(ann.getElementName())) {
				// 处理需要删除的注释
				ISourceRange sourceRange = ann.getSourceRange();
				int offset = sourceRange.getOffset();
				int length = sourceRange.getLength();
				
				// 未补偿
				ICompilationUnit compilationUnit = type.getCompilationUnit();
				IBuffer buffer = compilationUnit.getBuffer();
				
				int count = 1;
				// \r\n 或 \n
				while (!(buffer.getChar(offset - count) == '\n')) { // 一定存在,不存在到0还找不到的情况
					count++;
				}
				// 尝试判断是否为\r\n
				if (buffer.getChar(offset - count -  1) == '\r') {
					count++;
				}
				
				buffer.replace(offset - count, length + count, ""); // 删除
				
				buffer.save(new NullProgressMonitor(), true); // 刷新数据
				compilationUnit.close();
			}
		}
			 
	}

	public void setTemplateEngine(TemplateEngine templateEngine) {
		this.templateEngine = templateEngine;
	}

	public TemplateEngine getTemplateEngine() {
		return this.templateEngine;
	}
}
